<div :style="containerStyle" v-resize="updateViewSize">
  <svg :viewBox="viewBox" :style="svgStyle">
    <defs>
      <clipPath id="cut-content">
        <rect
          x="0"
          y="0"
          :width="view.size[0]"
          :height="view.size[1]"
        />
      </clipPath>
    </defs>
    <!-- X zoom window-->
    <rect
      v-bind="zoomControlStyle"

      :x="zoomWindow.x"
      :y="1-padding"
      :width="zoomWindow.width"
      :height="view.size[1] + 2 * padding - 2 "
      :rx="padding / 2"

      @mousedown="startZoom(0, $event)"
      @dblclick="resetZoomTransform(0)"
    />
    <!-- Y zoom window-->
    <rect
      v-bind="zoomControlStyle"

      :x="1-padding"
      :y="zoomWindow.y"
      :width="view.size[0] + 2 * padding - 2 "
      :height="zoomWindow.height"
      :rx="padding / 2"

      @mousedown="startZoom(1, $event)"
      @dblclick="resetZoomTransform(1)"
    />
    <!-- content border -->
    <rect
      v-bind="contentRectangleStyle"

      x="0"
      y="0"
      :width="view.size[0]"
      :height="view.size[1]"

      @mouseover="attachGaussianFinder"
      @mouseout="detachGaussianFinder"
      @dblclick="dblClick"
    />
    <!-- resulting transfer function line (zoom) -->
    <polyline
      v-bind="resultOpacityLineStyle"

      v-if="activeGaussian === -1 && !hoverPolyline"
      :points="transferFunctionPoints"
      clip-path="url(#cut-content)"
    />
    <!-- Inside content yZoom window -->
    <rect
      v-bind="insideZoomStyle"

      :x="0"
      :y="zoomWindow.y"
      :width="view.size[0]"
      :height="zoomWindow.height"

      @mousedown="startZoom(1, $event, true)"
      @mouseover="attachGaussianFinder"
      @mouseout="detachGaussianFinder"
      @dblclick="dblClick"
    />
    <!-- Inside content xZoom window -->
    <rect
      v-bind="insideZoomStyle"

      :x="zoomWindow.x"
      :y="0"
      :width="zoomWindow.width"
      :height="view.size[1]"

      @mousedown="startZoom(0, $event, true)"
      @mouseover="attachGaussianFinder"
      @mouseout="detachGaussianFinder"
      @dblclick="dblClick"
    />
    <!-- transfer function gaussian line (no zoom) -->
    <gaussian
      v-for="gaussian, idx in gaussians"
      :key="`gaussian-${idx}`"

      v-bind="isActiveGaussian(gaussian) ? activeGaussianOpacityStyle : gaussianOpacityStyle"

      :gaussian="toGaussianProps(gaussian)"
      clipPath="url(#cut-content)"

      @mousedown:bias="startGaussianBiasDrag(idx, $event)"
      @mousedown:background="startGaussianPositionDrag(idx, $event)"
      @dblclick:bias="resetGaussianBias(idx)"
      @mousedown:height="startGaussianHeightDrag(idx, $event)"
      @mousedown:width-left="startGaussianWidthDrag(idx, $event, -1)"
      @mousedown:width-right="startGaussianWidthDrag(idx, $event, 1)"

      @mouseover:background="attachGaussianFinder"
      @mouseout:background="detachGaussianFinder"
      @dblclick:background="dblClick"
    />
    <!-- zoomed transfer function line -->
    <polyline
      v-bind="hoverPolyline ? activeLinearOpacityStyle : linearOpacityStyle"

      :points="zoomedPolylinePoints"
      clip-path="url(#cut-content)"
    />
    <!-- Use to detect hover/active -->
    <polyline
      stroke="white"
      fill="none"
      opacity="0"
      :stroke-width="activeGaussianOpacityStyle.controlSize"

      :points="zoomedPolylinePoints"
      clip-path="url(#cut-content)"

      @dblclick="addControlPoint"
      @mouseout="offPolyline"
      @mouseover="onPolyline"
    />
    <!-- zoomed transfer function control points -->
    <circle
      v-for="cp, idx in zoomedControlPoints"
      :key="`control-point-${idx}`"
      v-show="isControlPointInside(cp) && hoverPolyline"

      v-bind="(selectedPoints && selectedPoints.includes(idx)) ? activeLinearOpacityControlStyle : linearOpacityControlStyle"

      :cx="cp.x"
      :cy="cp.y"

      @click="toggleSelection(idx)"
      @mousedown="startControlPointDrag(idx, $event)"
      @mouseout="offPolyline"
      @mouseover="onPolyline"
      @dblclick="deleteControlPoint(idx)"
    />
  </svg>
</div>
